import CryptoJS from "crypto-js";
import SparkMD5 from "spark-md5";
import JsEncrypt from "jsencrypt";

/** 加解密模块 */
export class CryptHelper {

    private keyId: string;
    private readonly publicKey: string;

    constructor(keyId: string, publicKey: string) {
        this.keyId = keyId;
        this.publicKey = publicKey;
    }

    sortParam(data: any): string {
        let keys = Object.keys(data);
        keys.sort(function (x, y) {
            if (x > y) {
                return 1;
            }
            return -1;
        });
        let paramArr = [];
        for (let k of keys) {
            paramArr.push(k + "=" + data[k]);
        }
        paramArr.push("key=5b8af47892d636624dde271aa5e19938");
        return paramArr.join("&");
    }

    signData(data: any) {
        let spark = new SparkMD5();
        return spark.append(this.sortParam(data)).end();
    }

    /** 生成n位随机 32 进制字符串 */
    randomKeys(): string {
        const charList = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
        let str = "", len = charList.length;
        for (let i = 0; i < 32; i++) {
            str += charList[Math.floor(Math.random() * len)];
        }
        return str;
    }

    /**
     * AES加密原始数据
     */
    aesEncrypt(keyWord: string, word: string): string | null {
        if (keyWord.length !== 16 && keyWord.length !== 32) {
            console.error("密钥必须是16位或32位");
            return null;
        }
        const key = CryptoJS.enc.Utf8.parse(keyWord);
        const src = CryptoJS.enc.Utf8.parse(word);
        const encrypted = CryptoJS.AES.encrypt(src, key, {
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7,
        });
        return encrypted.toString();

    }

    /**
     * AES解密加密的json数据
     */
    aesDecrypt(keyWord: string, word: string): string | null {
        if (keyWord.length !== 16 && keyWord.length !== 32) {
            console.error("密钥必须是16位或32位");
            return null;
        }
        const key = CryptoJS.enc.Utf8.parse(keyWord);
        const decrypt = CryptoJS.AES.decrypt(word, key, {
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7,
        });
        return CryptoJS.enc.Utf8.stringify(decrypt).toString();
    }

    /**
     * rsa算法公钥加密
     * @param params
     */
    rsaEncrypt(params: object | string): string | false {
        const Encrypt = new JsEncrypt();
        Encrypt.setPublicKey(this.publicKey);
        return Encrypt.encrypt(
            typeof params === "object" ? JSON.stringify(params) : params,
        );
    }

}



